//************************************************************************************
//**  
//**  Source name:   C:\Users\david main\Documents\µBITX ? Wire up ? HF SIGNALS_files\LCD_MCP23017_-TESTR_REV01.fcfx
//**  Title:         
//**  Description:   
//**  Device:        ARD.ATMEGA.ATMEGA328P
//**  
//**  Generated by:  Flowcode v9.0.0.23
//**  Date:          Sunday, December 06, 2020 13:12:01
//**  Users:         1
//**  Registered to: DAVIDJOINER (DAVIDJOINER)
//**  Licence key: 
//**  
//**     NOT FOR COMMERCIAL USE
//**  
//**  https://www.flowcode.co.uk
//**  
//************************************************************************************


#define MX_ARD

#define MX_CAL_ARD

#define MX_CLK_SPEED 16000000

#define FCP_NULL Unconnected_Port

#define MX_UART_ID
#define MX_UART_UCSRC

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <avr\io.h>
#include <avr\interrupt.h>
#include <avr\eeprom.h>
#include <avr\wdt.h>


/*========================================================================*\
   Use :Include the type definitions
\*========================================================================*/
#include "C:\ProgramData\MatrixTSL\FlowcodeV9\CAL\internals.c"



MX_UINT8 FCLV_LOOP1;
MX_UINT8 FCLV_LOOP2;
MX_UINT8 FCLV_LOOP3;
MX_UINT8 FCLV_LOOP4;
MX_UINT8 FCLV_LOOP5;
MX_UINT8 FCLV_LOOP6;
MX_UINT8 FCLV_LOOP7;
MX_UINT8 FCLV_LOOP8;


/*========================================================================*\
   Use :panel
       :Variable declarations
       :Macro function declarations
\*========================================================================*/
#define FCV_FALSE (0)
#define FCV_TRUE (1)


/*========================================================================*\
   Use :cal_i2c1
       :Variable declarations
       :Macro function declarations
\*========================================================================*/
#define MX_I2C_SDA_PORT_2 portc
#define MX_I2C_REF2 
#define MX_I2C_1 
#define MX_I2C_BMODE_2 (0)
#define MX_I2C_SDA_TRIS_2 trisc
#define MX_I2C_SCL_PIN_2 (5)
#define MX_I2C_SCL_PORT_2 portc
#define MX_I2C_STOPDEL_2 (0)
#define MX_I2C_SDA_PIN_2 (4)
#define MX_I2C_SCL_TRIS_2 trisc
#define MX_I2C_BAUD_2 (400000)
#define MX_I2C_CLOCKSTRETCHING_2 (1)
#define MX_I2C_CHANNEL_2 (0)


/*=----------------------------------------------------------------------=*\
   Use :cal_i2c1
       :Supplementary defines
\*=----------------------------------------------------------------------=*/
#define MX_MI2C

MX_GLOBAL MX_UINT8 FCV_07da2_cal_i2c1__TRANSADDR;
MX_GLOBAL MX_UINT32 FCV_07da2_cal_i2c1__CONSOLELOG;

void FC_CAL_I2C_Slave_Uninit_2();
void FCD_07da2_cal_i2c1__Prv_TextConsole(MX_CHAR *FCL_STR, MX_UINT16 FCLsz_STR, MX_UINT8 FCL_COLOUR, MX_UINT8 FCL_APPENDTIMESTAMP);
MX_UINT16 FC_CAL_I2C_Transaction_Write_2(MX_UINT8 *FCL_BUFFER, MX_UINT16 FCLsz_BUFFER, MX_UINT16 FCL_LENGTH);
void FC_CAL_I2C_Master_Stop_2();
void FC_CAL_I2C_Slave_Init_2(MX_UINT8 FCL_ADDRESS, MX_UINT8 FCL_MASK);
void FC_CAL_I2C_Master_Uninit_2();
MX_UINT8 FC_CAL_I2C_Slave_Status_2();
MX_UINT8 FC_CAL_I2C_Slave_TxByte_2(MX_UINT8 FCL_DATA);
void FC_CAL_I2C_Transaction_Uninit_2();
MX_UINT8 FC_CAL_I2C_Slave_RxByte_2(MX_UINT8 FCL_LAST);
void FC_CAL_I2C_Master_Init_2();
void FC_CAL_I2C_Master_Start_2();
MX_UINT16 FC_CAL_I2C_Transaction_Read_2(MX_UINT8 *FCL_BUFFER, MX_UINT16 FCLsz_BUFFER, MX_UINT16 FCL_LENGTH);
MX_UINT8 FC_CAL_I2C_Master_TxByte_2(MX_UINT8 FCL_DATA);
void FC_CAL_I2C_Master_Restart_2();
MX_UINT8 FC_CAL_I2C_Master_RxByte_2(MX_UINT8 FCL_LAST);
MX_UINT8 FC_CAL_I2C_Transaction_Init_2(MX_UINT8 FCL_ADDRESS);
void FCD_04071_LCD__Clear();
void FCD_04071_LCD__PrintString(MX_CHAR *FCL_TEXT, MX_UINT16 FCLsz_TEXT);
void FCD_04071_LCD__PrintAscii(MX_UINT8 FCL_CHARACTER);
void FCD_04071_LCD__PrintNumber(MX_SINT16 FCL_NUMBER);
void FCD_04071_LCD__RAMWrite(MX_UINT8 FCL_INDEX, MX_UINT8 FCL_D0, MX_UINT8 FCL_D1, MX_UINT8 FCL_D2, MX_UINT8 FCL_D3, MX_UINT8 FCL_D4, MX_UINT8 FCL_D5, MX_UINT8 FCL_D6, MX_UINT8 FCL_D7);
void FCD_04071_LCD__ClearLine(MX_UINT8 FCL_LINE);
void FCD_04071_LCD__Cursor(MX_UINT8 FCL_X, MX_UINT8 FCL_Y);
void FCD_04071_LCD__Command(MX_UINT8 FCL_INSTRUCTION);
void FCD_04071_LCD__PrintFormattedNumber(MX_UINT32 FCL_NUMBER, MX_BOOL FCL_FORMAT);
void FCD_04071_LCD__ScrollDisplay(MX_UINT8 FCL_POSITION, MX_UINT8 FCL_DIRECTION);
void FCD_04071_LCD__RawSend(MX_UINT8 FCL_DATA, MX_BOOL FCL_TYPE);
void FCD_04071_LCD__RemapCharacter(MX_UINT8 FCL_REMAPIDX, MX_UINT8 FCL_SEARCHCHARACTER, MX_UINT8 FCL_REPLACEMENTCHARACTER);
void FCD_04071_LCD__Start();

/*========================================================================*\
   Use :lcd_I2C1
       :Variable declarations
       :Macro function declarations
\*========================================================================*/
MX_GLOBAL MX_UINT8 FCV_0c591_lcd_I2C1__I2C_ADDRESS;
MX_GLOBAL MX_UINT8 FCV_0c591_lcd_I2C1__BACKLIGHT = (0x0);
MX_GLOBAL MX_UINT8 FCV_0c591_lcd_I2C1__ADDRESSOVERRIDE = (0x0);

void FCD_0c591_lcd_I2C1__Clear();
void FCD_0c591_lcd_I2C1__PrintString(MX_CHAR *FCL_TEXT, MX_UINT16 FCLsz_TEXT);
void FCD_0c591_lcd_I2C1__PrintAscii(MX_UINT8 FCL_CHARACTER);
void FCD_0c591_lcd_I2C1__PrintNumber(MX_SINT16 FCL_NUMBER);
void FCD_0c591_lcd_I2C1__RAMWrite(MX_UINT8 FCL_INDEX, MX_UINT8 FCL_D0, MX_UINT8 FCL_D1, MX_UINT8 FCL_D2, MX_UINT8 FCL_D3, MX_UINT8 FCL_D4, MX_UINT8 FCL_D5, MX_UINT8 FCL_D6, MX_UINT8 FCL_D7);
void FCD_0c591_lcd_I2C1__BacklightControl(MX_UINT8 FCL_STATE);
void FCD_0c591_lcd_I2C1__ClearLine(MX_UINT8 FCL_LINE);
void FCD_0c591_lcd_I2C1__Cursor(MX_UINT8 FCL_X, MX_UINT8 FCL_Y);
void FCD_0c591_lcd_I2C1__Command(MX_UINT8 FCL_INSTRUCTION);
void FCD_0c591_lcd_I2C1__PrintFormattedNumber(MX_UINT32 FCL_NUMBER, MX_BOOL FCL_FORMAT);
void FCD_0c591_lcd_I2C1__EnablePulse(MX_UINT8 FCL_DATA);
void FCD_0c591_lcd_I2C1__ScrollDisplay(MX_UINT8 FCL_POSITION, MX_UINT8 FCL_DIRECTION);
void FCD_0c591_lcd_I2C1__RawSend(MX_UINT8 FCL_DATA, MX_UINT8 FCL_MASK);
#define FCD_0c591_lcd_I2C1__RemapCharacter FCD_04071_LCD__RemapCharacter
void FCD_0c591_lcd_I2C1__Start();
void FCD_0c591_lcd_I2C1__SetI2CAddress(MX_UINT8 FCL_ADDRESS);

/*========================================================================*\
   Use :cal_i2c1
       :Variable declarations
       :Macro function declarations
\*========================================================================*/
#define MX_I2C_SDA_PORT_1 portc
#define MX_I2C_REF1 
#define MX_I2C_1 
#define MX_I2C_BMODE_1 (0)
#define MX_I2C_SDA_TRIS_1 trisc
#define MX_I2C_SCL_PIN_1 (5)
#define MX_I2C_SCL_PORT_1 portc
#define MX_I2C_STOPDEL_1 (0)
#define MX_I2C_SDA_PIN_1 (4)
#define MX_I2C_SCL_TRIS_1 trisc
#define MX_I2C_BAUD_1 (400000)
#define MX_I2C_CLOCKSTRETCHING_1 (1)
#define MX_I2C_CHANNEL_1 (0)


/*=----------------------------------------------------------------------=*\
   Use :cal_i2c1
       :Supplementary defines
\*=----------------------------------------------------------------------=*/
#define MX_MI2C

MX_GLOBAL MX_UINT8 FCV_07da1_cal_i2c1__TRANSADDR;
MX_GLOBAL MX_UINT32 FCV_07da1_cal_i2c1__CONSOLELOG;

void FC_CAL_I2C_Slave_Uninit_1();
void FCD_07da1_cal_i2c1__Prv_TextConsole(MX_CHAR *FCL_STR, MX_UINT16 FCLsz_STR, MX_UINT8 FCL_COLOUR, MX_UINT8 FCL_APPENDTIMESTAMP);
MX_UINT16 FC_CAL_I2C_Transaction_Write_1(MX_UINT8 *FCL_BUFFER, MX_UINT16 FCLsz_BUFFER, MX_UINT16 FCL_LENGTH);
void FC_CAL_I2C_Master_Stop_1();
void FC_CAL_I2C_Slave_Init_1(MX_UINT8 FCL_ADDRESS, MX_UINT8 FCL_MASK);
void FC_CAL_I2C_Master_Uninit_1();
MX_UINT8 FC_CAL_I2C_Slave_Status_1();
MX_UINT8 FC_CAL_I2C_Slave_TxByte_1(MX_UINT8 FCL_DATA);
void FC_CAL_I2C_Transaction_Uninit_1();
MX_UINT8 FC_CAL_I2C_Slave_RxByte_1(MX_UINT8 FCL_LAST);
void FC_CAL_I2C_Master_Init_1();
void FC_CAL_I2C_Master_Start_1();
MX_UINT16 FC_CAL_I2C_Transaction_Read_1(MX_UINT8 *FCL_BUFFER, MX_UINT16 FCLsz_BUFFER, MX_UINT16 FCL_LENGTH);
MX_UINT8 FC_CAL_I2C_Master_TxByte_1(MX_UINT8 FCL_DATA);
void FC_CAL_I2C_Master_Restart_1();
MX_UINT8 FC_CAL_I2C_Master_RxByte_1(MX_UINT8 FCL_LAST);
MX_UINT8 FC_CAL_I2C_Transaction_Init_1(MX_UINT8 FCL_ADDRESS);
MX_UINT8 FCD_0bd41_MCP23017__ReadPort(MX_UINT8 FCL_PORT, MX_UINT8 FCL_MASK);
void FCD_0bd41_MCP23017__ConfigureInversion(MX_UINT8 FCL_PORTA, MX_UINT8 FCL_PORTB);
MX_UINT8 FCD_0bd41_MCP23017__ReadPortPin(MX_UINT8 FCL_PORT, MX_UINT8 FCL_PIN);
void FCD_0bd41_MCP23017__WritePortPin(MX_UINT8 FCL_PORT, MX_UINT8 FCL_PIN, MX_UINT8 FCL_VALUE);
void FCD_0bd41_MCP23017__WritePort(MX_UINT8 FCL_PORT, MX_UINT8 FCL_MASK, MX_UINT8 FCL_VALUE);
void FCD_0bd41_MCP23017__ConfigurePullups(MX_UINT8 FCL_PORTA, MX_UINT8 FCL_PORTB);
MX_UINT8 FCD_0bd41_MCP23017__ReadRegister(MX_UINT8 FCL_ADDRESS);
void FCD_0bd41_MCP23017__WriteRegister(MX_UINT8 FCL_ADDRESS, MX_UINT8 FCL_VALUE);
void FCD_0bd41_MCP23017__Initialise();

/*========================================================================*\
   Use :Include the chip adaption layer
\*========================================================================*/
#include "C:\ProgramData\MatrixTSL\FlowcodeV9\CAL\includes.c"


/*========================================================================*\
   Use :cal_i2c1
       :Macro implementations
\*========================================================================*/
/*=----------------------------------------------------------------------=*\
   Use :Send text to the console
       :
       :Parameters for macro Prv_TextConsole:
       :  str[20] : MX_CHAR (by-ref)
       :  Colour : MX_UINT8
       :  AppendTimestamp : MX_UINT8
\*=----------------------------------------------------------------------=*/
void FCD_07da2_cal_i2c1__Prv_TextConsole(MX_CHAR *FCL_STR, MX_UINT16 FCLsz_STR, MX_UINT8 FCL_COLOUR, MX_UINT8 FCL_APPENDTIMESTAMP)
{
    //Local variable definitions
#define FCLsz_TSTR 20
    MX_CHAR FCL_TSTR[FCLsz_TSTR];


    #if (0)

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    //Local variable definitions
#undef FCLsz_TSTR
}


/*========================================================================*\
   Use :LCD
       :Macro implementations
\*========================================================================*/
/*=----------------------------------------------------------------------=*\
   Use :Clears the entire contents of the display.
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__Clear()
{




    FCD_04071_LCD__RawSend(0x01, 0);

    FCI_DELAYBYTE_MS(2);

    FCD_04071_LCD__RawSend(0x02, 0);

    FCI_DELAYBYTE_MS(2);

}

/*=----------------------------------------------------------------------=*\
   Use :Breaks down a string of text and sends it to the LCD via the private RawSend(byte, mask) macro
       :
       :Parameters for macro PrintString:
       :  Text[20] : Enter the text or variable to print to the LCD
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__PrintString(MX_CHAR *FCL_TEXT, MX_UINT16 FCLsz_TEXT)
{
    //Local variable definitions
    MX_UINT8 FCL_IDX = (0x0);
    MX_UINT8 FCL_COUNT;


    // .count = Length$ (.Text)
    FCL_COUNT = FCI_GETLENGTH(FCL_TEXT, FCLsz_TEXT);

    while (FCL_IDX < FCL_COUNT)
    {

        #if (0) // 0 > 0

        //Code has been optimised out by the pre-processor
        #else


            FCD_04071_LCD__RawSend(FCL_TEXT[FCL_IDX], 0x10);

        #endif

        // .Idx = .Idx + 1
        FCL_IDX = FCL_IDX + 1;


    }


}

/*=----------------------------------------------------------------------=*\
   Use :Takes the ascii value for a character and prints the character
       :
       :Parameters for macro PrintAscii:
       :  character : Holds an ascii value.
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__PrintAscii(MX_UINT8 FCL_CHARACTER)
{

    FCD_04071_LCD__RawSend(FCL_CHARACTER, 0x10);



}

/*=----------------------------------------------------------------------=*\
   Use :Based on v5 macro, will allow you to print a number. This is limited to a signed-INT, -32768 to 32767
       :
       :Parameters for macro PrintNumber:
       :  Number : Enter the number or variable to print to the LCD
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__PrintNumber(MX_SINT16 FCL_NUMBER)
{
    //Local variable definitions
#define FCLsz_S 10
    MX_CHAR FCL_S[FCLsz_S];


    // .s = ToString$ (.Number)
    FCI_TOSTRING(FCL_NUMBER, FCL_S,10);

    FCD_04071_LCD__PrintString(FCL_S, FCLsz_S);

    //Local variable definitions
#undef FCLsz_S
}

/*=----------------------------------------------------------------------=*\
   Use :Modifies the internal memory of the LCD to allow for up to 8 customised characters to be created and stored in the device memory
       :
       :Parameters for macro RAMWrite:
       :  Index : Values 0 to 7
       :  d0 : MX_UINT8
       :  d1 : MX_UINT8
       :  d2 : MX_UINT8
       :  d3 : MX_UINT8
       :  d4 : MX_UINT8
       :  d5 : MX_UINT8
       :  d6 : MX_UINT8
       :  d7 : MX_UINT8
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__RAMWrite(MX_UINT8 FCL_INDEX, MX_UINT8 FCL_D0, MX_UINT8 FCL_D1, MX_UINT8 FCL_D2, MX_UINT8 FCL_D3, MX_UINT8 FCL_D4, MX_UINT8 FCL_D5, MX_UINT8 FCL_D6, MX_UINT8 FCL_D7)
{

    FCD_04071_LCD__RawSend(64 + (FCL_INDEX << 3), 0);

    FCI_DELAYBYTE_MS(2);

    FCD_04071_LCD__RawSend(FCL_D0, 0x10);

    FCD_04071_LCD__RawSend(FCL_D1, 0x10);

    FCD_04071_LCD__RawSend(FCL_D2, 0x10);

    FCD_04071_LCD__RawSend(FCL_D3, 0x10);

    FCD_04071_LCD__RawSend(FCL_D4, 0x10);

    FCD_04071_LCD__RawSend(FCL_D5, 0x10);

    FCD_04071_LCD__RawSend(FCL_D6, 0x10);

    FCD_04071_LCD__RawSend(FCL_D7, 0x10);

    FCD_04071_LCD__Clear();

}

/*=----------------------------------------------------------------------=*\
   Use :Clears a single line on the display and then moves the cursor to the start of the line to allow you to start populating the line with data.
       :
       :Parameters for macro ClearLine:
       :  Line : The line to clear, zero being the first (top) line of the display
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__ClearLine(MX_UINT8 FCL_LINE)
{
    //Local variable definitions
    MX_UINT8 FCL_X;


    if (FCL_LINE < 4)
    {

        FCD_04071_LCD__Cursor(0, FCL_LINE);

        // .x = 0
        FCL_X = 0;

        while (FCL_X < 20)
        {


            FCD_04071_LCD__RawSend(' ', 0x10);

            // .x = .x + 1
            FCL_X = FCL_X + 1;


        }

        FCD_04071_LCD__Cursor(0, FCL_LINE);

    // } else {

    }

}

/*=----------------------------------------------------------------------=*\
   Use :Moves the cursor on the LCD Display
       :
       :Parameters for macro Cursor:
       :  x : Set the cursor position in the X plane, 0 is the left most cell
       :  y : Set the cursor position in the Y plane, 0 is the top most cell
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__Cursor(MX_UINT8 FCL_X, MX_UINT8 FCL_Y)
{



    #if (0) // 4 == 1

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    #if (0) // 4 == 2

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    #if (1) // 4 == 4

        if (FCL_Y == 0)
        {

            // .y = 0x80
            FCL_Y = 0x80;

        } else {

            if (FCL_Y == 1)
            {

                // .y = 0xC0
                FCL_Y = 0xC0;

            } else {

                #if (0) // 20 == 16

                //Code has been optimised out by the pre-processor
                #else

                    #if (1) // 20 == 20

                        if (FCL_Y == 2)
                        {

                            // .y = 0x94
                            FCL_Y = 0x94;

                        } else {

                            // .y = 0xd4
                            FCL_Y = 0xd4;

                        }

                    // #else

                    //Code has been optimised out by the pre-processor
                    #endif

                #endif

            }

        }

    // #else

    //Code has been optimised out by the pre-processor
    #endif

    FCD_04071_LCD__RawSend(FCL_Y + FCL_X, 0);

    FCI_DELAYBYTE_MS(2);

    //Comment:
    //EB2 LCDs have occasional problems here if cursor command isn't called twice

    FCD_04071_LCD__RawSend(FCL_Y + FCL_X, 0);

    FCI_DELAYBYTE_MS(2);

}

/*=----------------------------------------------------------------------=*\
   Use :Use this method/macro to send a specific command to the LCD. Refer to the Matrix Multimedia EB006 datasheet for a list of supported instructions. For Non-Matrix LCD's refer to the manufacturers datasheet.
       :
       :Parameters for macro Command:
       :  instruction : Send a defined command to the LCD Screen. See datasheet for supported commands.
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__Command(MX_UINT8 FCL_INSTRUCTION)
{

    FCD_04071_LCD__RawSend(FCL_INSTRUCTION, 0);

    FCI_DELAYBYTE_MS(2);

}

/*=----------------------------------------------------------------------=*\
   Use :Will allow you to print a number up to 32-bits with signed or unsigned formatting.
       :Signed = -2147483648 to 2147483647
       :Unsigned = 0 to 4294967295
       :
       :Parameters for macro PrintFormattedNumber:
       :  Number : Enter the number or variable to print to the LCD
       :  Format : 0=Signed, 1=Unsigned
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__PrintFormattedNumber(MX_UINT32 FCL_NUMBER, MX_BOOL FCL_FORMAT)
{
    //Local variable definitions
#define FCLsz_S 15
    MX_CHAR FCL_S[FCLsz_S];


    if (FCL_FORMAT == 1)
    {

        // .s = STRING UNSIGNED .Number
        FCI_UTOS32(FCL_NUMBER, FCL_S,15);

    } else {

        // .s = STRING SIGNED .Number
        FCI_ITOS32((MX_SINT32)(FCL_NUMBER), FCL_S,15);

    }

    FCD_04071_LCD__PrintString(FCL_S, FCLsz_S);

    //Local variable definitions
#undef FCLsz_S
}

/*=----------------------------------------------------------------------=*\
   Use :Scrolls the display left or right by a number of given positions.
       :
       :Parameters for macro ScrollDisplay:
       :  Position : Holds the number of positions to shift the display
       :  Direction : 0 = left, 1 = right
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__ScrollDisplay(MX_UINT8 FCL_POSITION, MX_UINT8 FCL_DIRECTION)
{
    //Local variable definitions
    MX_UINT8 FCL_CMD = (0x0);


    // .cmd = 0
    FCL_CMD = 0;

    if (FCL_DIRECTION == 0)
    {

        // .cmd = 0x18
        FCL_CMD = 0x18;


    } else {

        // .cmd = 0x1C
        FCL_CMD = 0x1C;


    }

    if (FCL_CMD != 0 && FCL_POSITION != 0)
    {

        while (FCL_POSITION != 0)
        {

            FCD_04071_LCD__RawSend(FCL_CMD, 0);

            // .Position = .Position - 1
            FCL_POSITION = FCL_POSITION - 1;


        }

    // } else {

    }

}

/*=----------------------------------------------------------------------=*\
   Use :Sends data to the LCD display
       :
       :Parameters for macro RawSend:
       :  data : The data byte to send to the LCD
       :  type : A boolean to indicate command type: true to write data, false to write a command
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__RawSend(MX_UINT8 FCL_DATA, MX_BOOL FCL_TYPE)
{
    //Local variable definitions
    MX_UINT8 FCL_NIBBLE;


    //Comment:
    //Output upper nibble of the byte

    #if (1) // 0 == 0

        // Pin_Data_0 = 0
        // Pin_Data_1 = 0
        // Pin_Data_2 = 0
        // Pin_Data_3 = 0
        // Pin_RS = 0
        // Pin_E = 0
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);

        #if (0)

        //Code has been optimised out by the pre-processor
        // #else

        #endif

        // .nibble = (.data >> 4)
        // Pin_Data_0 = (.nibble & 0x01)
        // .nibble = .nibble >> 1
        // Pin_Data_1 = (.nibble & 0x01)
        // .nibble = .nibble >> 1
        // Pin_Data_2 = (.nibble & 0x01)
        // .nibble = .nibble >> 1
        // Pin_Data_3 = (.nibble & 0x01)
        FCL_NIBBLE = (FCL_DATA >> 4);
        SET_PORT_PIN(C, 4, (FCL_NIBBLE & 0x01));
        FCL_NIBBLE = FCL_NIBBLE >> 1;
        SET_PORT_PIN(C, 4, (FCL_NIBBLE & 0x01));
        FCL_NIBBLE = FCL_NIBBLE >> 1;
        SET_PORT_PIN(C, 4, (FCL_NIBBLE & 0x01));
        FCL_NIBBLE = FCL_NIBBLE >> 1;
        SET_PORT_PIN(C, 4, (FCL_NIBBLE & 0x01));

    // #else

    //Code has been optimised out by the pre-processor
    #endif

    //Comment:
    //Output byte to pins

    #if (0) // 0 == 1

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    //Comment:
    //Output byte to port

    #if (0) // 0 == 2

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    if (FCL_TYPE)
    {

        // Pin_RS = 1
        SET_PORT_PIN(C, 4, 1);

    // } else {

    }

    #if (0)

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    FCI_DELAYBYTE_US(100);

    //Comment:
    //Set Enable high, pause then set low
    //to acknowledge the data has been 
    //submitted.

    // Pin_E = 1
    SET_PORT_PIN(C, 4, 1);

    FCI_DELAYBYTE_US(100);

    // Pin_E = 0
    SET_PORT_PIN(C, 4, 0);

    FCI_DELAYBYTE_US(100);

    #if (1) // 0 == 0

        // Pin_Data_0 = 0
        // Pin_Data_1 = 0
        // Pin_Data_2 = 0
        // Pin_Data_3 = 0
        // Pin_RS = 0
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);

        // .nibble = (.data & 0xf)
        // Pin_Data_0 = (.nibble & 0x01)
        // .nibble = .nibble >> 1
        // Pin_Data_1 = (.nibble & 0x01)
        // .nibble = .nibble >> 1
        // Pin_Data_2 = (.nibble & 0x01)
        // .nibble = .nibble >> 1
        // Pin_Data_3 = (.nibble & 0x01)
        FCL_NIBBLE = (FCL_DATA & 0xf);
        SET_PORT_PIN(C, 4, (FCL_NIBBLE & 0x01));
        FCL_NIBBLE = FCL_NIBBLE >> 1;
        SET_PORT_PIN(C, 4, (FCL_NIBBLE & 0x01));
        FCL_NIBBLE = FCL_NIBBLE >> 1;
        SET_PORT_PIN(C, 4, (FCL_NIBBLE & 0x01));
        FCL_NIBBLE = FCL_NIBBLE >> 1;
        SET_PORT_PIN(C, 4, (FCL_NIBBLE & 0x01));

        if (FCL_TYPE)
        {

            // Pin_RS = 1
            SET_PORT_PIN(C, 4, 1);

        // } else {

        }

        FCI_DELAYBYTE_US(100);

        // Pin_E = 1
        SET_PORT_PIN(C, 4, 1);

        FCI_DELAYBYTE_US(100);

        // Pin_E = 0
        SET_PORT_PIN(C, 4, 0);

        FCI_DELAYBYTE_US(100);

    // #else

    //Code has been optimised out by the pre-processor
    #endif

}

/*=----------------------------------------------------------------------=*\
   Use :Assigns a remap character allowing the PrintString function to automatically swap between pre-defined characters. 
       :The characters can be custom (in the range 0-9) or can point to an existing character in the LCD character map.
       :
       :Parameters for macro RemapCharacter:
       :  RemapIdx : Remap Index, Range: 0 to (Remap Characters - 1)
       :  SearchCharacter : Character to look for a replace
       :  ReplacementCharacter : New character value to use in place of the search character.
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__RemapCharacter(MX_UINT8 FCL_REMAPIDX, MX_UINT8 FCL_SEARCHCHARACTER, MX_UINT8 FCL_REPLACEMENTCHARACTER)
{

    #if (0) // 0 > 0

    //Code has been optimised out by the pre-processor
    // #else

    #endif

}

/*=----------------------------------------------------------------------=*\
   Use :Startup routine required by the hardware device.
       :Automatically clears the display after initialising.
\*=----------------------------------------------------------------------=*/
void FCD_04071_LCD__Start()
{




    #if (1) // 0 == 0

        // Pin_Data_0 = 0
        // Pin_Data_1 = 0
        // Pin_Data_2 = 0
        // Pin_Data_3 = 0
        // Pin_RS = 0
        // Pin_E = 0
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);
        SET_PORT_PIN(C, 4, 0);

    // #else

    //Code has been optimised out by the pre-processor
    #endif

    #if (0) // 0 == 1

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    #if (0) // 0 == 2

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    #if (0)

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    FCI_DELAYBYTE_MS(12);

    FCD_04071_LCD__RawSend(0x33, 0);

    FCI_DELAYBYTE_MS(2);

    FCD_04071_LCD__RawSend(0x33, 0);

    FCI_DELAYBYTE_MS(2);

    #if (0) // 0 > 0

    //Code has been optimised out by the pre-processor
    #else

        FCD_04071_LCD__RawSend(0x32, 0);

        FCI_DELAYBYTE_MS(2);

        FCD_04071_LCD__RawSend(0x2c, 0);

    #endif

    FCI_DELAYBYTE_MS(2);

    FCD_04071_LCD__RawSend(0x06, 0);

    FCI_DELAYBYTE_MS(2);

    FCD_04071_LCD__RawSend(0x0c, 0);

    FCI_DELAYBYTE_MS(2);

    FCD_04071_LCD__RawSend(0x01, 0);

    FCI_DELAYBYTE_MS(2);

    FCD_04071_LCD__RawSend(0x02, 0);

    FCI_DELAYBYTE_MS(2);

    FCD_04071_LCD__Clear();

    #if (0) // 0 > 0

    //Code has been optimised out by the pre-processor
    // #else

    #endif

}


/*========================================================================*\
   Use :lcd_I2C1
       :Macro implementations
\*========================================================================*/
/*=----------------------------------------------------------------------=*\
   Use :
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__Clear()
{

    FCD_0c591_lcd_I2C1__RawSend(0x01, 0);

    FCI_DELAYBYTE_MS(2);

}

/*=----------------------------------------------------------------------=*\
   Use :Parameters for macro PrintString:
       :  Text[20] : MX_CHAR (by-ref)
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__PrintString(MX_CHAR *FCL_TEXT, MX_UINT16 FCLsz_TEXT)
{
    //Local variable definitions
    MX_UINT8 FCL_IDX = (0x0);
    MX_UINT8 FCL_COUNT;


    // .count = Length$ (.Text)
    FCL_COUNT = FCI_GETLENGTH(FCL_TEXT, FCLsz_TEXT);

    while (FCL_IDX < FCL_COUNT)
    {

        FCD_0c591_lcd_I2C1__RawSend(FCL_TEXT[FCL_IDX], 0x10);

        // .Idx = .Idx + 1
        FCL_IDX = FCL_IDX + 1;


    }

}

/*=----------------------------------------------------------------------=*\
   Use :Takes the ascii value for a character and prints the character
       :
       :Parameters for macro PrintAscii:
       :  character : MX_UINT8
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__PrintAscii(MX_UINT8 FCL_CHARACTER)
{

    FCD_0c591_lcd_I2C1__RawSend(FCL_CHARACTER, 0x10);

}

/*=----------------------------------------------------------------------=*\
   Use :Allows you to print a number. This is limited to a signed-INT, -32768 to 32767
       :
       :Parameters for macro PrintNumber:
       :  Number : MX_SINT16
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__PrintNumber(MX_SINT16 FCL_NUMBER)
{
    //Local variable definitions
#define FCLsz_S 10
    MX_CHAR FCL_S[FCLsz_S];


    // .s = ToString$ (.Number)
    FCI_TOSTRING(FCL_NUMBER, FCL_S,10);

    FCD_0c591_lcd_I2C1__PrintString(FCL_S, FCLsz_S);

    //Local variable definitions
#undef FCLsz_S
}

/*=----------------------------------------------------------------------=*\
   Use :Modifies the internal memory of the LCD to allow for up to 8 customised characters to be created and stored in the device memory
       :
       :Parameters for macro RAMWrite:
       :  Index : MX_UINT8
       :  d0 : MX_UINT8
       :  d1 : MX_UINT8
       :  d2 : MX_UINT8
       :  d3 : MX_UINT8
       :  d4 : MX_UINT8
       :  d5 : MX_UINT8
       :  d6 : MX_UINT8
       :  d7 : MX_UINT8
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__RAMWrite(MX_UINT8 FCL_INDEX, MX_UINT8 FCL_D0, MX_UINT8 FCL_D1, MX_UINT8 FCL_D2, MX_UINT8 FCL_D3, MX_UINT8 FCL_D4, MX_UINT8 FCL_D5, MX_UINT8 FCL_D6, MX_UINT8 FCL_D7)
{

    FCD_0c591_lcd_I2C1__RawSend(64 + (FCL_INDEX << 3), 0);

    FCI_DELAYBYTE_MS(2);

    FCD_0c591_lcd_I2C1__RawSend(FCL_D0, 0x10);

    FCD_0c591_lcd_I2C1__RawSend(FCL_D1, 0x10);

    FCD_0c591_lcd_I2C1__RawSend(FCL_D2, 0x10);

    FCD_0c591_lcd_I2C1__RawSend(FCL_D3, 0x10);

    FCD_0c591_lcd_I2C1__RawSend(FCL_D4, 0x10);

    FCD_0c591_lcd_I2C1__RawSend(FCL_D5, 0x10);

    FCD_0c591_lcd_I2C1__RawSend(FCL_D6, 0x10);

    FCD_0c591_lcd_I2C1__RawSend(FCL_D7, 0x10);

    FCD_0c591_lcd_I2C1__Clear();

}

/*=----------------------------------------------------------------------=*\
   Use :Parameters for macro BacklightControl:
       :  State : MX_UINT8
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__BacklightControl(MX_UINT8 FCL_STATE)
{
    //Local variable definitions
#define FCLsz_DOUT 2
    MX_UINT8 FCL_DOUT[FCLsz_DOUT];


    #if (0)

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    //Local variable definitions
#undef FCLsz_DOUT
}

/*=----------------------------------------------------------------------=*\
   Use :Parameters for macro ClearLine:
       :  Line : MX_UINT8
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__ClearLine(MX_UINT8 FCL_LINE)
{
    //Local variable definitions
    MX_UINT8 FCL_X;


    if (FCL_LINE < 4)
    {

        FCD_0c591_lcd_I2C1__Cursor(0, FCL_LINE);

        // .x = 0
        FCL_X = 0;

        while (FCL_X < 20)
        {

            FCD_0c591_lcd_I2C1__RawSend(' ', 0x10);

            // .x = .x + 1
            FCL_X = FCL_X + 1;


        }

        FCD_0c591_lcd_I2C1__Cursor(0, FCL_LINE);

    // } else {

    }

}

/*=----------------------------------------------------------------------=*\
   Use :Moves the cursor on the LCD Display
       :
       :Parameters for macro Cursor:
       :  x : MX_UINT8
       :  y : MX_UINT8
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__Cursor(MX_UINT8 FCL_X, MX_UINT8 FCL_Y)
{

    #if (0) // 4 == 1

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    #if (0) // 4 == 2

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    #if (1) // 4 == 4

        if (FCL_Y == 0)
        {

            // .y = 0x80
            FCL_Y = 0x80;

        } else {

            if (FCL_Y == 1)
            {

                // .y = 0xC0
                FCL_Y = 0xC0;

            } else {

                #if (0) // 20 == 16

                //Code has been optimised out by the pre-processor
                #else

                    #if (1) // 20 == 20

                        if (FCL_Y == 2)
                        {

                            // .y = 0x94
                            FCL_Y = 0x94;

                        } else {

                            // .y = 0xd4
                            FCL_Y = 0xd4;

                        }

                    // #else

                    //Code has been optimised out by the pre-processor
                    #endif

                #endif

            }

        }

    // #else

    //Code has been optimised out by the pre-processor
    #endif

    FCD_0c591_lcd_I2C1__RawSend(FCL_Y + FCL_X, 0);

    FCI_DELAYBYTE_MS(2);

}

/*=----------------------------------------------------------------------=*\
   Use :Use this method/macro to send a specific command to the LCD. Refer to the Matrix Multimedia EB006 datasheet for a list of supported instructions. For Non-Matrix LCD's refer to the manufacturers datasheet.
       :
       :Parameters for macro Command:
       :  instruction : MX_UINT8
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__Command(MX_UINT8 FCL_INSTRUCTION)
{

    FCD_0c591_lcd_I2C1__RawSend(FCL_INSTRUCTION, 0);

    FCI_DELAYBYTE_MS(2);

}

/*=----------------------------------------------------------------------=*\
   Use :Will allow you to print a number up to 32-bits with signed or unsigned formatting.
       :Signed = -2147483648 to 2147483647
       :Unsigned = 0 to 4294967295
       :
       :Parameters for macro PrintFormattedNumber:
       :  Number : Enter the number or variable to print to the LCD
       :  Format : 0=Signed, 1=Unsigned
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__PrintFormattedNumber(MX_UINT32 FCL_NUMBER, MX_BOOL FCL_FORMAT)
{
    //Local variable definitions
#define FCLsz_S 15
    MX_CHAR FCL_S[FCLsz_S];


    if (FCL_FORMAT == 1)
    {

        // .s = STRING UNSIGNED .Number
        FCI_UTOS32(FCL_NUMBER, FCL_S,15);

    } else {

        // .s = STRING SIGNED .Number
        FCI_ITOS32((MX_SINT32)(FCL_NUMBER), FCL_S,15);

    }

    FCD_0c591_lcd_I2C1__PrintString(FCL_S, FCLsz_S);

    //Local variable definitions
#undef FCLsz_S
}

/*=----------------------------------------------------------------------=*\
   Use :Parameters for macro EnablePulse:
       :  data : MX_UINT8
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__EnablePulse(MX_UINT8 FCL_DATA)
{
    //Local variable definitions
    MX_UINT8 FCL_HI;
    MX_UINT8 FCL_LO;
    MX_UINT8 FCL_TBYTE;
#define FCLsz_DOUT 2
    MX_UINT8 FCL_DOUT[FCLsz_DOUT];


    //Comment:
    //Swaps upper and lower nibbles, so lower 4 are now cleared vs upper 4.

    // .hi = (.data & 0x0F) << 4
    // .lo = (.data & 0xF0) >> 4
    // .tbyte = (.hi | .lo)
    FCL_HI = (FCL_DATA & 0x0F) << 4;
    FCL_LO = (FCL_DATA & 0xF0) >> 4;
    FCL_TBYTE = (FCL_HI | FCL_LO);

    #if (0)

    //Code has been optimised out by the pre-processor
    #else

        // .dout[0] = .tbyte | 0x0C
        FCL_DOUT[0] = FCL_TBYTE | 0x0C;

        FC_CAL_I2C_Transaction_Write_2(FCL_DOUT, 2, 1);

        FCI_DELAYBYTE_US(100);

        // .dout[0] = .tbyte | 0x08
        FCL_DOUT[0] = FCL_TBYTE | 0x08;

        FC_CAL_I2C_Transaction_Write_2(FCL_DOUT, 2, 1);

    #endif

    //Local variable definitions
#undef FCLsz_DOUT
}

/*=----------------------------------------------------------------------=*\
   Use :Scrolls the display left or right by a number of given positions.
       :
       :Parameters for macro ScrollDisplay:
       :  position : MX_UINT8
       :  direction : MX_UINT8
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__ScrollDisplay(MX_UINT8 FCL_POSITION, MX_UINT8 FCL_DIRECTION)
{
    //Local variable definitions
    MX_UINT8 FCL_CMD;


    // .cmd = 0
    FCL_CMD = 0;

    switch (FCL_DIRECTION)
    {
        case 0:
        {
            // .cmd = 0x18
            FCL_CMD = 0x18;

            break;
        }
        case 'l':
        {
            // .cmd = 0x18
            FCL_CMD = 0x18;

            break;
        }
        case 'L':
        {
            // .cmd = 0x18
            FCL_CMD = 0x18;

            break;
        }
        case 1:
        {
            // .cmd = 0x1C
            FCL_CMD = 0x1C;

            break;
        }
        case 'r':
        {
            // .cmd = 0x1C
            FCL_CMD = 0x1C;

            break;
        }
        case 'R':
        {
            // .cmd = 0x1C
            FCL_CMD = 0x1C;

            break;
        }
        // default:

    }

    if (FCL_CMD > 0)
    {

        while (FCL_POSITION != 0)
        {

            FCD_0c591_lcd_I2C1__RawSend(FCL_CMD, 0);

            // .Position = .Position - 1
            FCL_POSITION = FCL_POSITION - 1;


        }

    // } else {

    }

}

/*=----------------------------------------------------------------------=*\
   Use :Sends data to the LCD display
       :
       :Parameters for macro RawSend:
       :  data : MX_UINT8
       :  mask : MX_UINT8
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__RawSend(MX_UINT8 FCL_DATA, MX_UINT8 FCL_MASK)
{
    //Local variable definitions
    MX_UINT8 FCL_NIBBLE;
    MX_UINT8 FCL_I2DATA;


    //Comment:
    //Clears lower 4 bits and shift upper bits to right x 4

    // .i2data = (.data & 0xF0) >> 4
    FCL_I2DATA = (FCL_DATA & 0xF0) >> 4;

    //Comment:
    //Comment

    FCD_0c591_lcd_I2C1__EnablePulse(FCL_I2DATA | FCL_MASK);

    //Comment:
    //Clears upper 4 bits

    // .nibble = (.data & 0xF0)
    // .i2data = .data ^ .nibble
    FCL_NIBBLE = (FCL_DATA & 0xF0);
    FCL_I2DATA = FCL_DATA ^ FCL_NIBBLE;

    FCD_0c591_lcd_I2C1__EnablePulse(FCL_I2DATA | FCL_MASK);

}

/*=----------------------------------------------------------------------=*\
   Use :Startup routine required by the hardware device.
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__Start()
{

    if (FCV_0c591_lcd_I2C1__ADDRESSOVERRIDE == 1)
    {

        //Comment:
        //Ignore as we have already set the overridden address

    } else {

        // I2C_Address = Address
        FCV_0c591_lcd_I2C1__I2C_ADDRESS = 39;

    }

    FC_CAL_I2C_Transaction_Init_2(FCV_0c591_lcd_I2C1__I2C_ADDRESS);

    FCI_DELAYBYTE_MS(12);

    FCD_0c591_lcd_I2C1__EnablePulse(3);

    FCI_DELAYBYTE_MS(4);

    FCD_0c591_lcd_I2C1__EnablePulse(3);

    FCD_0c591_lcd_I2C1__EnablePulse(3);

    FCI_DELAYBYTE_MS(4);

    FCD_0c591_lcd_I2C1__EnablePulse(2);

    FCD_0c591_lcd_I2C1__RawSend(0x2C, 0);

    FCD_0c591_lcd_I2C1__RawSend(0x06, 0);

    FCD_0c591_lcd_I2C1__RawSend(0x0C, 0);

    FCD_0c591_lcd_I2C1__RawSend(0x01, 0);

    FCI_DELAYBYTE_MS(2);

}

/*=----------------------------------------------------------------------=*\
   Use :Allows the I2C device address to be dynamically changed in software without
       :having to re-compile. Can be called before the first Start macro or at any point 
       :after.
       :
       :Parameters for macro SetI2CAddress:
       :  Address : New I2C Device Address excluding R/W bit - Range 0 - 127
\*=----------------------------------------------------------------------=*/
void FCD_0c591_lcd_I2C1__SetI2CAddress(MX_UINT8 FCL_ADDRESS)
{

    // I2C_Address = .Address
    FCV_0c591_lcd_I2C1__I2C_ADDRESS = FCL_ADDRESS;

    FC_CAL_I2C_Transaction_Init_2(FCV_0c591_lcd_I2C1__I2C_ADDRESS);

    // AddressOverride = 1
    FCV_0c591_lcd_I2C1__ADDRESSOVERRIDE = 1;

}


/*========================================================================*\
   Use :cal_i2c1
       :Macro implementations
\*========================================================================*/
/*=----------------------------------------------------------------------=*\
   Use :Send text to the console
       :
       :Parameters for macro Prv_TextConsole:
       :  str[20] : MX_CHAR (by-ref)
       :  Colour : MX_UINT8
       :  AppendTimestamp : MX_UINT8
\*=----------------------------------------------------------------------=*/
void FCD_07da1_cal_i2c1__Prv_TextConsole(MX_CHAR *FCL_STR, MX_UINT16 FCLsz_STR, MX_UINT8 FCL_COLOUR, MX_UINT8 FCL_APPENDTIMESTAMP)
{
    //Local variable definitions
#define FCLsz_TSTR 20
    MX_CHAR FCL_TSTR[FCLsz_TSTR];


    #if (0)

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    //Local variable definitions
#undef FCLsz_TSTR
}


/*========================================================================*\
   Use :MCP23017
       :Macro implementations
\*========================================================================*/
/*=----------------------------------------------------------------------=*\
   Use :Reads a value to one of the ports with a mask.
       :Configures the masked bits to be inputs before reading the input value.
       :
       :Parameters for macro ReadPort:
       :  Port : 0=PortA, 1=PortB
       :  Mask : Allows port bits to be modified without effecting other bits, 255 = write full port.
       :
       :Returns : MX_UINT8
\*=----------------------------------------------------------------------=*/
MX_UINT8 FCD_0bd41_MCP23017__ReadPort(MX_UINT8 FCL_PORT, MX_UINT8 FCL_MASK)
{
    //Local variable definitions
    MX_UINT8 FCL_REG;
    MX_UINT8 FCR_RETVAL;


    if (FCL_PORT == 0)
    {

        //Comment:
        //DDR

        if (FCL_MASK == 0xFF)
        {

            FCD_0bd41_MCP23017__WriteRegister(0, FCL_MASK);

        } else {

            FCL_REG = FCD_0bd41_MCP23017__ReadRegister(0);

            // .Reg = .Reg | .Mask
            FCL_REG = FCL_REG | FCL_MASK;

            FCD_0bd41_MCP23017__WriteRegister(0, FCL_REG);

        }

        //Comment:
        //Port Pin

        FCR_RETVAL = FCD_0bd41_MCP23017__ReadRegister(0x12);

    } else {

        if (FCL_PORT == 1)
        {

            //Comment:
            //DDR

            if (FCL_MASK == 0xFF)
            {

                FCD_0bd41_MCP23017__WriteRegister(1, FCL_MASK);

            } else {

                FCL_REG = FCD_0bd41_MCP23017__ReadRegister(1);

                // .Reg = .Reg | .Mask
                FCL_REG = FCL_REG | FCL_MASK;

                FCD_0bd41_MCP23017__WriteRegister(1, FCL_REG);

            }

            //Comment:
            //Port Pin

            FCR_RETVAL = FCD_0bd41_MCP23017__ReadRegister(0x13);

        } else {

            // .Return = 0
            FCR_RETVAL = 0;

        }

    }

    // .Return = .Return & .Mask
    FCR_RETVAL = FCR_RETVAL & FCL_MASK;

    return (FCR_RETVAL);

}

/*=----------------------------------------------------------------------=*\
   Use :Configures the pin inversion for the two ports. 
       :Disabled on all pins by default.
       :
       :Parameters for macro ConfigureInversion:
       :  PortA : Port A inversion sent as an 8-bit value, 0 = Disabled, 1 = Enabled
       :  PortB : Port B inversion sent as an 8-bit value, 0 = Disabled, 1 = Enabled
\*=----------------------------------------------------------------------=*/
void FCD_0bd41_MCP23017__ConfigureInversion(MX_UINT8 FCL_PORTA, MX_UINT8 FCL_PORTB)
{

    FCD_0bd41_MCP23017__WriteRegister(0x02, FCL_PORTA);

    FCD_0bd41_MCP23017__WriteRegister(0x03, FCL_PORTB);

}

/*=----------------------------------------------------------------------=*\
   Use :Reads a single port pin from one of the ports.
       :Configures the pins to be an input before reading the input value.
       :Returns 0 or 1 corresponding to the value on the port pin.
       :
       :Parameters for macro ReadPortPin:
       :  Port : 0=PortA, 1=PortB
       :  Pin : Port pin to read. Range: 0-7
       :
       :Returns : MX_UINT8
\*=----------------------------------------------------------------------=*/
MX_UINT8 FCD_0bd41_MCP23017__ReadPortPin(MX_UINT8 FCL_PORT, MX_UINT8 FCL_PIN)
{
    //Local variable definitions
    MX_UINT8 FCR_RETVAL;


    if (FCL_PIN < 8)
    {

        FCR_RETVAL = FCD_0bd41_MCP23017__ReadPort(FCL_PORT, 1 << FCL_PIN);

        if (FCR_RETVAL)
        {

            // .Return = 1
            FCR_RETVAL = 1;

        // } else {

        }

    } else {

        // .Return = 0
        FCR_RETVAL = 0;

    }

    return (FCR_RETVAL);

}

/*=----------------------------------------------------------------------=*\
   Use :Writes a single port pin on one of the ports.
       :Configures the pins to be an output before writing the input value.
       :
       :Parameters for macro WritePortPin:
       :  Port : 0=PortA, 1=PortB
       :  Pin : Port pin to read. Range: 0-7
       :  Value : Value to output on the selected pin. Range: 0-1
\*=----------------------------------------------------------------------=*/
void FCD_0bd41_MCP23017__WritePortPin(MX_UINT8 FCL_PORT, MX_UINT8 FCL_PIN, MX_UINT8 FCL_VALUE)
{

    if (FCL_PIN < 8)
    {

        FCD_0bd41_MCP23017__WritePort(FCL_PORT, 1 << FCL_PIN, FCL_VALUE << FCL_PIN);

    // } else {

    }

}

/*=----------------------------------------------------------------------=*\
   Use :Writes a value to one of the ports with a mask.
       :Configures the masked bits to be outputs before writing the output value.
       :
       :Parameters for macro WritePort:
       :  Port : 0=PortA, 1=PortB
       :  Mask : Allows port bits to be modified without effecting other bits, 255 = write full port.
       :  Value : Value to write. Range 0-255
\*=----------------------------------------------------------------------=*/
void FCD_0bd41_MCP23017__WritePort(MX_UINT8 FCL_PORT, MX_UINT8 FCL_MASK, MX_UINT8 FCL_VALUE)
{
    //Local variable definitions
    MX_UINT8 FCL_REG;


    if (FCL_PORT == 0)
    {

        if (FCL_MASK == 255)
        {

            //Comment:
            //DDR

            FCD_0bd41_MCP23017__WriteRegister(0, ~FCL_MASK);

            //Comment:
            //Port Pin

            FCD_0bd41_MCP23017__WriteRegister(0x14, FCL_VALUE);

        } else {

            //Comment:
            //DDR

            FCL_REG = FCD_0bd41_MCP23017__ReadRegister(0);

            // .Reg = .Reg & ~ .Mask
            FCL_REG = FCL_REG & ~FCL_MASK;

            FCD_0bd41_MCP23017__WriteRegister(0, FCL_REG);

            //Comment:
            //Port Pin

            FCL_REG = FCD_0bd41_MCP23017__ReadRegister(0x14);

            // .Reg = .Reg & ~ .Mask
            // .Reg = .Reg | (.Value & .Mask)
            FCL_REG = FCL_REG & ~FCL_MASK;
            FCL_REG = FCL_REG | (FCL_VALUE & FCL_MASK);

            FCD_0bd41_MCP23017__WriteRegister(0x14, FCL_REG);

        }

    } else {

        if (FCL_PORT == 1)
        {

            if (FCL_MASK == 255)
            {

                //Comment:
                //DDR

                FCD_0bd41_MCP23017__WriteRegister(1, ~FCL_MASK);

                //Comment:
                //Port Pin

                FCD_0bd41_MCP23017__WriteRegister(0x15, FCL_VALUE);

            } else {

                //Comment:
                //DDR

                FCL_REG = FCD_0bd41_MCP23017__ReadRegister(1);

                // .Reg = .Reg & ~ .Mask
                FCL_REG = FCL_REG & ~FCL_MASK;

                FCD_0bd41_MCP23017__WriteRegister(1, FCL_REG);

                //Comment:
                //Port Pin

                FCL_REG = FCD_0bd41_MCP23017__ReadRegister(0x15);

                // .Reg = .Reg & ~ .Mask
                // .Reg = .Reg | (.Value & .Mask)
                FCL_REG = FCL_REG & ~FCL_MASK;
                FCL_REG = FCL_REG | (FCL_VALUE & FCL_MASK);

                FCD_0bd41_MCP23017__WriteRegister(0x15, FCL_REG);

            }

        } else {

            //Comment:
            //Port out of range

        }

    }

}

/*=----------------------------------------------------------------------=*\
   Use :Configures the pullups for the two ports.
       :Disabled on all pins by default.
       :
       :Parameters for macro ConfigurePullups:
       :  PortA : Port A pull ups sent as an 8-bit value, 0 = Disabled, 1 = Enabled
       :  PortB : Port B pull ups sent as an 8-bit value, 0 = Disabled, 1 = Enabled
\*=----------------------------------------------------------------------=*/
void FCD_0bd41_MCP23017__ConfigurePullups(MX_UINT8 FCL_PORTA, MX_UINT8 FCL_PORTB)
{

    FCD_0bd41_MCP23017__WriteRegister(0x0C, FCL_PORTA);

    FCD_0bd41_MCP23017__WriteRegister(0x0D, FCL_PORTB);

}

/*=----------------------------------------------------------------------=*\
   Use :Reads an 8-bit value from a register on the I/O expander device.
       :
       :Parameters for macro ReadRegister:
       :  Address : Register address to write to. Range: 0-15
       :
       :Returns : MX_UINT8
\*=----------------------------------------------------------------------=*/
MX_UINT8 FCD_0bd41_MCP23017__ReadRegister(MX_UINT8 FCL_ADDRESS)
{
    //Local variable definitions
#define FCLsz_DATA 1
    MX_UINT8 FCL_DATA[FCLsz_DATA];
    MX_UINT8 FCR_RETVAL;


    // .data[0] = .Address
    FCL_DATA[0] = FCL_ADDRESS;

    FC_CAL_I2C_Transaction_Write_1(FCL_DATA, 1, 1);

    FC_CAL_I2C_Transaction_Read_1(FCL_DATA, 1, 1);

    // .Return = .data[0]
    FCR_RETVAL = FCL_DATA[0];


    return (FCR_RETVAL);

    //Local variable definitions
#undef FCLsz_DATA
}

/*=----------------------------------------------------------------------=*\
   Use :Writes an 8-bit value to a register on the I/O expander device.
       :
       :Parameters for macro WriteRegister:
       :  Address : Register address to write to. Range: 0-15
       :  Value : Value to write. Range: 0-255
\*=----------------------------------------------------------------------=*/
void FCD_0bd41_MCP23017__WriteRegister(MX_UINT8 FCL_ADDRESS, MX_UINT8 FCL_VALUE)
{
    //Local variable definitions
#define FCLsz_DATA 2
    MX_UINT8 FCL_DATA[FCLsz_DATA];


    // .data[0] = .Address
    // .data[1] = .Value
    FCL_DATA[0] = FCL_ADDRESS;
    FCL_DATA[1] = FCL_VALUE;

    FC_CAL_I2C_Transaction_Write_1(FCL_DATA, 2, 2);


    //Local variable definitions
#undef FCLsz_DATA
}

/*=----------------------------------------------------------------------=*\
   Use :
\*=----------------------------------------------------------------------=*/
void FCD_0bd41_MCP23017__Initialise()
{

    #if (0)

    //Code has been optimised out by the pre-processor
    // #else

    #endif

    FC_CAL_I2C_Transaction_Init_1(0 | 0x20);

}



/*========================================================================*\
   Use :Main
\*========================================================================*/
int main()
{
    MCUSR=0x00;


    // Name: Component Macro, Type: Component Macro: lcd_I2C1::Start()
    FCD_0c591_lcd_I2C1__Start();

    // Name: MCP23017 INITIALISE, Type: Component Macro: MCP23017::Initialise()
    FCD_0bd41_MCP23017__Initialise();

    // Name: Loop, Type: Loop: While 1
    while (1)
    {

        // Name: WRITE HIGH TO MCP23017 PORT B, Type: Component Macro: MCP23017::WritePort(1, 255, 255)
        FCD_0bd41_MCP23017__WritePort(1, 255, 255);

        // Name: Delay, Type: Delay: 1 s
        FCI_DELAYBYTE_S(1);

        // Name: PRINT STRING TO LCD, Type: Component Macro: lcd_I2C1::PrintString("  LCD TEST")
        FCD_0c591_lcd_I2C1__PrintString("  LCD TEST", 11);

        // Name: WRITE LOW TO MCP23017  PORT B, Type: Component Macro: MCP23017::WritePort(1, 255, 0)
        FCD_0bd41_MCP23017__WritePort(1, 255, 0);

        // Name: Delay, Type: Delay: 1 s
        FCI_DELAYBYTE_S(1);

        // Name: CLEAR LCD, Type: Component Macro: lcd_I2C1::Clear()
        FCD_0c591_lcd_I2C1__Clear();


    }

    mainendloop: goto mainendloop;
}



/*========================================================================*\
   Use :Interrupt
\*========================================================================*/





